Android 分区存储常见问题解答
要在 Google Play 上发布,开发者需要将应用的目标 API 级别 (targetSdkVersion) 更新到 API 级别 30 (Android 11) 或者更高版本。针对新上架的应用,这个政策自 8 月开始生效;现有应用更新新的版本,这个政策的要求将自 11 月开始生效。
目标 API 级别 (targetSdkVersion)
https://developer.android.google.cn/distribute/best-practices/develop/target-sdk
API 30 所带来的一个巨大变更是,应用需要使用分区存储 (Scoped Storage)。
变更之大,对于大型应用来说堪称恐怖。更糟糕的是,我们在网上看到的有关如何适配分区存储的建议,有一些建议十分令人迷惑,甚至会误导我们。
为了帮您排忧解难,我们收集了一些有关分区存储的常见问题,同时也为如何适配您的应用提供了一些建议和可能的替代方案。
Q: android:requestLegacyStorage 会被移除吗?
android:requestLegacyStorage="true"
https://developer.android.google.cn/training/data-storage/use-cases#opt-out-in-production-app
Q: android:preserveLegacyStorage 是如何工作的?
Q: 如果我的应用没有访问照片、视频或音频文件,是否仍然需要请求 READ_EXTERNAL_STORAGE 权限?
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
android:maxSdkVersion
https://developer.android.google.cn/guide/topics/manifest/uses-permission-element#maxSdk
△ 上图为拥有 "脆弱用户数据" 应用的卸载对话框。
对话框中包含了一个复选框,
设置了该标记后,存储文件的最佳位置将取决于其内容。包含敏感或私人信息的文件应当存储在 Context#getFilesDir() 所返回的目录中;而不敏感的数据则应存储于 Context#getExternalFilesDir() 所返回的目录中。
Play 政策
https://support.google.com/googleplay/android-developer/answer/10467955
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
Q: 我想要与其他应用共享文件,是否需要使用 SAF?
直接分享: 使用 Intent.ACTION_SEND 可以让您的用户通过各种格式与设备上的其他应用共享数据。如果您使用这种方式,使用 AndroidX 的 FileProvider 来将 file:// Uri 自动转换为 content:// Uri 可能会对您有所帮助。
创建您自己的 DocumentProvider: 这可以让您的应用继续处理应用的私有目录 ( Context#getFilesDirs() 或 Context#getExternalFilesDirs()) 中内容的同时,仍可以向使用系统文件选择器的其他应用提供访问权限。(请注意,可以在卸载应用后继续保存这些文件——参阅上文中的 android:hasFragileUserData="true" 设置来了解其使用方式。)
直接分享
https://developer.android.google.cn/training/sharing/sendAndroidX 的 FileProvider
https://developer.android.google.cn/training/secure-file-sharing/setup-sharing创建您自己的 DocumentProvider
https://medium.com/androiddevelopers/building-a-documentsprovider-f7f2fb38e86a
最后的思考
Scoped Storage 是一项旨在改善用户隐私保护的重大变更。不过仍然有很多方法可以处理不依赖使用存储访问框架 (Storage Access Framework) 的内容。
如果要存储的数据仅适用于您的应用,那么我们强烈建议使用应用特定目录。
如果数据是媒体文件,例如照片、视频或者音频,那么可以使用 MediaStore。注意,从 Android 10 开始,提供内容不再需要请求权限。
也别忘了可以通过 ACTION_SEND 来与其他应用共享数据 (或允许它们与您的应用共享数据)!
应用特定目录
https://developer.android.google.cn/training/data-storage/app-specific使用 MediaStore
https://developer.android.google.cn/training/data-storage/shared/media不再需要请求权限
https://developer.android.google.cn/training/data-storage/shared/media#scoped_storage_enabled其他应用共享数据
https://developer.android.google.cn/training/sharing/send与您的应用共享数据
https://developer.android.google.cn/training/sharing/receive
推荐阅读